import qrcode
import os
import sys
import importlib.util

CONFIG_API_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), "config_api.py"))
spec = importlib.util.spec_from_file_location("config_api", CONFIG_API_PATH)
config_api = importlib.util.module_from_spec(spec)
sys.modules["config_api"] = config_api
spec.loader.exec_module(config_api)

def get_qrcode():
    # 集成B站官方扫码API，获取真实二维码链接
    import requests
    api_url = "https://passport.bilibili.com/x/passport-login/web/qrcode/generate?source=main-fe-header&go_url=https://www.bilibili.com/"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36",
        "Referer": "https://www.bilibili.com/",
        "Origin": "https://www.bilibili.com"
    }
    try:
        resp = requests.get(api_url, headers=headers, timeout=5)
        resp.raise_for_status()
        data = resp.json()
        print(f"[get_qrcode] B站API返回: {data}")
        if data.get("code") == 0 and data.get("data", {}).get("url"):
            qrcode_url = data["data"]["url"]
            qrcode_key = data["data"]["qrcode_key"]
            img = qrcode.make(qrcode_url)
            img_path = os.path.join(os.path.dirname(__file__), "qrcode.png")
            img.save(img_path)
            print(f"[get_qrcode] 二维码生成成功: {qrcode_url}, key: {qrcode_key}")
            return img_path, qrcode_url, qrcode_key
        else:
            print(f"[get_qrcode] 获取B站扫码链接失败: {data}")
            raise Exception(f"获取B站扫码链接失败: {data}")
    except Exception as e:
        print(f"[get_qrcode] 异常: {e}")
        raise


def poll_qrcode_status(qrcode_key, is_alt=False):
    import requests
    from urllib.parse import urlparse, parse_qs
    poll_url = f"https://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key={qrcode_key}&source=main-fe-header"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36",
        "Referer": "https://www.bilibili.com/",
        "Origin": "https://www.bilibili.com",
        "Accept": "application/json, text/plain, */*",
        "Accept-Language": "zh-CN,zh;q=0.9",
        "Connection": "keep-alive"
    }
    try:
        print(f"[poll_qrcode_status] 调用，qrcode_key={qrcode_key}")
        resp = requests.get(poll_url, headers=headers, timeout=5)
        print(f"[poll_qrcode_status] poll_url={poll_url}")
        try:
            resp.raise_for_status()
        except requests.exceptions.HTTPError as e:
            print(f"[poll_qrcode_status] HTTPError: {e}, status={resp.status_code}")
            print(f"[poll_qrcode_status] 响应内容: {resp.text}")
            if resp.status_code == 412:
                print("[poll_qrcode_status] 二维码已失效或被使用，请刷新二维码")
                return {"code": 412, "msg": "二维码已失效或被使用，请刷新二维码"}
            else:
                print(f"[poll_qrcode_status] 异常: {e}")
                return {"code": -1, "msg": str(e)}
        data = resp.json()
        print(f"[poll_qrcode_status] B站轮询返回: {data}")
        # 统一二维码失效判断：B站data.data.code==86038 或 data.data.message含失效
        cookie_valid = False
        if data.get("code") == 0 and isinstance(data.get("data"), dict):
            d = data["data"]
            if (d.get("code") == 86038) or (d.get("message") and "失效" in d.get("message")):
                print("[poll_qrcode_status] 二维码已失效或被使用，请刷新二维码")
                return {"code": 412, "msg": "二维码已失效或被使用，请刷新二维码"}
            if d.get("url"):
                url = d["url"]
                print(f"[poll_qrcode_status] 登录成功url: {url}")
                # 直接从url参数提取cookie
                parsed = urlparse(url)
                params = parse_qs(parsed.query)
                print(f"[poll_qrcode_status] url参数: {params}")
                # SESSDATA 保留完整字符串（含逗号及后续内容）
                sessdata = params.get("SESSDATA", [None])[0]
                cookie = {
                    "SESSDATA": sessdata,
                    "DedeUserID": params.get("DedeUserID", [None])[0],
                    "bili_jct": params.get("bili_jct", [None])[0]
                }
                print(f"[poll_qrcode_status] 解析到Cookie: {cookie}")
                # 校验cookie有效性（长度、非空）
                if cookie["SESSDATA"] and len(cookie["SESSDATA"]) >= 16 and cookie["DedeUserID"] and cookie["bili_jct"]:
                    # 进一步请求B站接口确认cookie有效
                    try:
                        check_headers = {
                            'User-Agent': 'Mozilla/5.0',
                            'Referer': 'https://www.bilibili.com/'
                        }
                        check_cookies = {
                            'SESSDATA': cookie['SESSDATA'],
                            'DedeUserID': cookie['DedeUserID'],
                            'bili_jct': cookie['bili_jct']
                        }
                        check_resp = requests.get('https://api.bilibili.com/x/web-interface/nav', cookies=check_cookies, headers=check_headers, timeout=5)
                        check_data = check_resp.json()
                        if check_data.get('code') == 0 and check_data.get('data', {}).get('mid'):
                            cookie_valid = True
                            save_cookie(cookie, is_alt=is_alt)
                            print(f"[poll_qrcode_status] Cookie有效，已写入: {cookie}，is_alt={is_alt}")
                        else:
                            print(f"[poll_qrcode_status] Cookie无效: {check_data}")
                    except Exception as e:
                        print(f"[poll_qrcode_status] Cookie有效性检测异常: {e}")
                else:
                    print(f"[poll_qrcode_status] Cookie字段不完整或过短: {cookie}")
                data["cookie_valid"] = cookie_valid
                data["cookie"] = cookie
        print(f"[poll_qrcode_status] 返回data: {data}")
        return data
    except Exception as e:
        print(f"[poll_qrcode_status] 异常: {e}")
        return {"code": -1, "msg": str(e)}

def get_qrcode_status():
    # TODO: 返回扫码状态，实际应与bilibili-api-python联动
    return {"status": "waiting"}

def get_cookie():
    try:
        config = config_api.get_config()
        return config.get("bilibili", {}).get("cookie", {})
    except Exception:
        return {}

def save_cookie(cookie, is_alt=False):
    try:
        cookie_str = {k: str(v) if v is not None else '' for k, v in cookie.items()}
        config = config_api.get_config()
        new_bili = {}
        if is_alt:
            new_bili["alt_cookie"] = cookie_str
        else:
            new_bili["cookie"] = cookie_str
            if "DedeUserID" in cookie_str and cookie_str["DedeUserID"]:
                new_bili["uid"] = int(cookie_str["DedeUserID"])
        if "bilibili" not in config:
            config["bilibili"] = {}
        config["bilibili"].update(new_bili)
        config_api.save_config(config)
    except Exception:
        pass
